package com.gomoku

import java.io.Serializable

// 游戏结束原因
enum class GameOverReason {
    LOST,           // 失败
    RIVAL_ADMIT,    // 对手认输
    SELF_ADMIT,     // 自己认输
    WON             // 胜利
}

/**
 * 协议类构造方法。
 * @param mType     类型
 * @param mUsername 用户名
 */
open class GomokuProtocol(val mType: Type, var mUsername: String): Serializable {
    // 协议类型
    enum class Type {
        FIND_USERS,     // 寻找其它用户
        GAME_OVER,      // 游戏结束
        INVITE_REQUEST, // 挑战请求
        INVITE_RESULT,  // 挑战结果
        LOGON,          // 登录
        PUT_PIECE,      // 放置棋子
        QUIT_GAME       // 退出游戏
    }

    companion object {
        const val SERVER_IP: String = "192.168.1.108"   // 服务器 IP 地址
        const val SERVER_PORT: Int = 10000              // 服务器端口号
    }
}

/**
 * 寻找用户请求的构造方法。
 * @param username  用户名
 */
class FindUsersRequest(username: String):
    GomokuProtocol(Type.FIND_USERS, username)

/**
 * 寻找用户结果的构造方法。
 * @param usernameList  用户名列表
 */
class FindUsersResult(usernameList: List<String>):
    GomokuProtocol(Type.FIND_USERS, "") {
    val mUsernameList = usernameList    // 用户名列表
}

/**
 * 游戏结束的构造方法。
 * @param reason    结束原因
 * @param rivalName 对手的名字
 */
class GameOver(reason: GameOverReason, rivalName: String):
    GomokuProtocol(Type.GAME_OVER, rivalName) {
    val mReason = reason    // 结束原因
}

/**
 * 挑战请求的构造方法。
 * @param rivalName 对手的名字
 * @param username  用户名
 */
class InviteRequest(rivalName: String, username: String):
    GomokuProtocol(Type.INVITE_REQUEST, username) {
    val mRivalName = rivalName  // 对手的名字
}

/**
 * 挑战结果的构造方法。
 * @param accept    接受挑战则为 true，否则为 false
 * @param rivalName 对手的名字
 * @param username  用户名
 */
class InviteResult(accept: Boolean, rivalName: String, username: String):
    GomokuProtocol(Type.INVITE_RESULT, username) {
    val mAccept = accept        // 接受挑战则为 true，否则为 false
    val mRivalName = rivalName  // 对手的名字
}

/**
 * 登录请求的构造方法。
 * @param username  用户名
 */
class LogonRequest(username: String):
    GomokuProtocol(Type.LOGON, username)

/**
 * 登录结果的构造方法。
 * @param username  用户名
 */
class LogonResult(username: String):
    GomokuProtocol(Type.LOGON, username)

/**
 * 放置棋子的构造方法。
 * @param rivalName 对手的名字
 * @param x, y      棋子位置（窗口坐标）
 */
class PutPiece(rivalName: String, x: Int, y: Int):
    GomokuProtocol(Type.PUT_PIECE, rivalName) {
    val mX = x  // x 坐标（窗口坐标）
    val mY = y  // y 坐标（窗口坐标）
}

/**
 * 退出游戏的构造方法。
 * @param username  用户名
 */
class QuitGame(username: String):
    GomokuProtocol(Type.QUIT_GAME, username)
